// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

// hero状态
enum State {
    stand = 1,
    attack
}
// 动画名称
enum Anima {
    idle = 'idle',
    run = 'run',
    attack1 = 'attack1',
    attack2 = 'attack2',
    attack3 = 'attack3',
    
}

const Input = {}

const {ccclass, property} = cc._decorator;

@ccclass
export default class NewClass extends cc.Component {

    // 速度
    @property
    speed: number = 0;

    // 方向
    @property
    sp: cc.Vec2 = null;

    // hero状态
    @property
    heroSate: State  = null;

    // hero动画
    @property
    heroAni: cc.Animation = null;

    // hero动画状态
    @property
    annima:Anima  = null

    // 连击
    @property
    combo: number = 0;


    // 刚体在世界坐标下的(线性速度)
    @property
    lv: cc.Vec2  = null

    // LIFE-CYCLE CALLBACKS:

    onLoad () {
        // cc.director.getPhysicsManager().debugDrawFlags = 1;

        this.speed = 200
        this.sp = cc.v2(0,0)

        this.heroSate = State.stand

        this.annima = Anima.idle

        this.heroAni = this.node.getChildByName('body').getComponent(cc.Animation)

        
        
        // 动画监听 播放结束
        this.heroAni.on(cc.Animation.EventType.FINISHED, this.onAnimationFinish, this)

        // 键盘监听
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this)
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this)
    }

    // start () {}

    update (dt:number) { 
        

        // 根据英雄状态进行对应操作(修改状态)
        switch (this.heroSate) {
            case State.stand:
                if (Input[cc.macro.KEY.j]) {
                    // 修改状态为攻击
                    this.heroSate = State.attack
                }
                break;
        
            default:
                break;
        }

        // 根据状态执行对应操作
        switch (this.heroSate) {
            case State.stand:
                this.move()
                break;

            case State.attack:
                this.attack();
                break;

            default:
                break;
        }

    }

    onDestroy() {
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this)
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this)
        this.heroAni.off(cc.Animation.EventType.FINISHED, this.onAnimationFinish, this)
    }


    onKeyDown(e: cc.Event.EventKeyboard):void {
        // cc.log(e.keyCode)
        Input[e.keyCode] = 1

    }

    onKeyUp(e:cc.Event.EventKeyboard):void {
        Input[e.keyCode] = 0

    }

    // 移动
    move():void {
        let scaleX = Math.abs(this.node.scaleX)
        let annima = this.annima
        if (Input[cc.macro.KEY.a] || Input[cc.macro.KEY.left]) {
            // <--
            this.sp.x = -1
            this.node.scaleX = - scaleX
            annima = Anima.run
        }else if(Input[cc.macro.KEY.d] || Input[cc.macro.KEY.right]){
            this.sp.x = 1
            this.node.scaleX = scaleX
            annima = Anima.run
        } else {
            this.sp.x = 0
            annima = Anima.idle
        }

        this.setSpeed()
        // 修改动画
        this.setAnima(annima)
    }

    // 攻击
    attack():void {

        let annima = this.annima
        if (Input[cc.macro.KEY.j]) {
            // 播放攻击动画
            // cc.log('即将播放攻击动画')
            if (this.combo == 0) {
                annima = Anima.attack1
            }else if (this.combo == 1) {
                annima = Anima.attack2
            }else if (this.combo == 2) {
                annima = Anima.attack3
            }
        }
        this.sp.x = 0

        this.setSpeed()

        // 修改动画
        this.setAnima(annima)
        
    }

    // 改变速度(向量)
    setSpeed():void {
        // 刚体
        let rigidBody = this.node.getComponent(cc.RigidBody)
        // 刚体的线性速度
        this.lv = rigidBody.linearVelocity
        // 速度和方向
        if (this.sp.x) {
            this.lv.x = this.sp.x * this.speed;
        } else {
            this.lv.x = 0
        }
        // 速度赋值
        rigidBody.linearVelocity = this.lv
    }

    /**
     * 播放新动画
     * @param animiat 
     */
    setAnima(animiat: Anima):void {
        if(!animiat || this.annima == animiat) {
            return
        }
        // cc.log('old {}, new {}',this.annima, animiat)
        this.annima = animiat
        // 播放新动画
        // cc.log('当前播放动画:' + animiat)
        this.heroAni.play(animiat)
    }

    /**
     * 动画监听事件
     * @param e 
     * @param data 
     */
    onAnimationFinish(e:cc.Event.EventCustom, data:cc.AnimationState) {
        // 重置为静态动画
        let animiateName = data.name
        // cc.log('动画结束', animiateName)
        if (animiateName == Anima.attack1 || animiateName == Anima.attack2 || animiateName == Anima.attack3) {
            this.heroSate = State.stand
            // 连击判定
            this.combo = (this.combo + 1) % 3

            setTimeout(()=> {
                if(this.heroSate == State.stand) {
                    return
                }
                this.combo = 0
            }, 10000)
        }
    }
}
